import BaseLock from "./BaseLock.mjs";
import ZKResponseEnum from "../entity/ZKResponseEnum.mjs";
import RenewalTask from "../schedule/RenewalTask.mjs";
import ZKDelKeyTask from "../schedule/ZKDelKeyTask.mjs";

export default class ZkLock extends BaseLock {
    client;
    renewalTask;
    zkDelKeyTask;

    constructor(client, key, value, ttl, reentrant) {
        super(key, value, ttl, reentrant);
        this.client = client;
    }

    async lock() {
        try {
            // 抢锁
            const zkResult = await this.client.setKey(this.key, this.value, this.ttl);
            const _this = this;
            if (ZKResponseEnum.SUCCESS.code === zkResult.code) {
                _this.renewalTask = new RenewalTask();
                _this.zkDelKeyTask = new ZKDelKeyTask(_this.key, _this.ttl);

                // 开启任务
                _this.renewalTask.start(_this.ttl, () => _this.zkDelKeyTask.modifyExpire(this.ttl));
                _this.zkDelKeyTask.start(() => _this.release());

                this.hold = true;
                BaseLock.holdLocks.add(this.key);
                return this.hold;
            }
        } catch (e) {
            this.hold = false;
            throw e;
        }
    }

    release() {
        this.client.delKey(this.key);
        this.renewalTask.stop();
        this.zkDelKeyTask.stop();
        this.client.close();
    }

    getClient() {
        return this.client;
    }
}
